#include "gameroom.h"
#include "gameselect.h"
#include <QPixmap>
#include <QPainter>
#include <QPen>
#include <QDebug>
#include <QIcon>
#include <QPushButton>
#include <QSound>
#include <QList>
#include <QTimer>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
GameRoom::GameRoom(QWidget *parent) : QWidget(parent)
{
    this->setFixedSize(1000,800);
    //设置窗口图标
    this->setWindowIcon(QIcon(":res/ico.png"));
    //设置窗口标签
    this->setWindowTitle("游戏界面");
    //创建一个返回按钮
    QPushButton* returnButton = new QPushButton(this);
    //设置位置和按钮照片
    returnButton->move(900,700);
    returnButton->setIcon(QIcon(":res/up.png"));
    //创建信号槽
    connect(returnButton,&QPushButton::clicked,[=]{
        //关闭当前页面
        this->close();
        GameSelect *gameRn = new GameSelect();
        //显示上个页面
        gameRn->show();
        QSound::play(":res/clicked.wav");
    });
    // 初始化贪吃蛇
    snakeList.push_back(QRectF(this->width() * 0.5, this->height() * 0.5,
                               kSnakeNodeWidth, kSnakeNodeHeight));
    moveUp();
    moveUp();
    // 初始化⻝物
    creatNewFood();

    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [=](){
        int cnt = 1;
        // 判断是否贪吃蛇和⻝物是否相交
        if (snakeList.front().intersects(foodRect)) {
            creatNewFood();
            ++cnt;
            QSound::play(":res/eatfood.wav");
        }
        while(cnt--) {
            // 处理蛇的移动
            switch (moveDirect) {
            case kSnakeDirect::UP:
                moveUp();
                break;
            case kSnakeDirect::DOWN:
                moveDown();
                break;
            case kSnakeDirect::LEFT:
                moveLeft();
                break;
            case kSnakeDirect::RIGHT:
                moveRight();
                break;
            default:
                qDebug() << "⾮法移动⽅向";
                break;
            }
        }
        // 删除最后⼀个节点
        snakeList.pop_back();
        update();
    });
    //设置开始暂停按钮
    QPushButton *startbtn = new QPushButton(this);
    QPushButton *stopbtn = new QPushButton(this);
    QFont font("楷体", 20);
    //设置按钮的位置
    startbtn->move(860,150);
    stopbtn->move(860,200);
    //设置按钮⽂本
    startbtn->setText("开始");
    stopbtn->setText("暂停");
    //设置按钮样式
    startbtn->setStyleSheet("QPushButton{border:0px;}");
    stopbtn->setStyleSheet("QPushButton{border:0px;}");
    //设置按钮字体格式
    startbtn->setFont(font);
    stopbtn->setFont(font);
    //蛇移动
    connect(startbtn,&QPushButton::clicked,this,[=](){
        isGameStart = true;
        timer->start(moveDefount);
        sound = new QSound(":res/Trepak.wav"); //声⾳路S径
             sound->play(); //播放
             sound->setLoops(-1); //循环播放
    });
    //蛇暂停
    connect(stopbtn,&QPushButton::clicked,this,[=](){
        isGameStart = false;
        timer->stop();//停止工作
        sound->stop();//停止播放
    });
    //设置蛇2的移动方向
    QPushButton *Up = new QPushButton(this);
    QPushButton *Down = new QPushButton(this);
    QPushButton *Left = new QPushButton(this);
    QPushButton *Right = new QPushButton(this);
    Up->move(880,400);
    Down->move(880,480);
    Left->move(840,440);
    Right->move(920,440);
    Up->setStyleSheet("QPushButton{border:0px;}");
    Up->setFont(font);
    Up->setText("↑");
    Down->setStyleSheet("QPushButton{border:0px;}");
    Down->setFont(font);
    Down->setText("↓");
    Left->setStyleSheet("QPushButton{border:0px;}");
    Left->setFont(font);
    Left->setText("←");
    Right->setStyleSheet("QPushButton{border:0px;}");
    Right->setFont(font);
    Right->setText("→");
    connect(Up,&QPushButton::clicked,this,[=](){
        if(moveDirect != kSnakeDirect::DOWN)
            moveDirect = kSnakeDirect::UP;
    });
    connect(Down,&QPushButton::clicked,this,[=](){
        if(moveDirect != kSnakeDirect::UP)
            moveDirect = kSnakeDirect::DOWN;
    });
    connect(Left,&QPushButton::clicked,this,[=](){
        if(moveDirect != kSnakeDirect::RIGHT)
            moveDirect = kSnakeDirect::LEFT;
    });
    connect(Right,&QPushButton::clicked,this,[=](){
        if(moveDirect != kSnakeDirect::LEFT)
            moveDirect = kSnakeDirect::RIGHT;
        });
    //设置退出按钮,并给他设置样式
    QPushButton *exitBtn=new QPushButton(this);
    exitBtn->setText("退出");
    exitBtn->move(870,750);
    exitBtn->setFont(font);
    //设置消息盒子
    QMessageBox *msg=new QMessageBox(this);
    QPushButton *okBtn =new QPushButton("OK");
    QPushButton *cancelBtn =new QPushButton("cancel");
    msg->addButton(okBtn,QMessageBox::AcceptRole);
    msg->addButton(cancelBtn,QMessageBox::RejectRole);
    msg->setWindowTitle("退出游戏");
    msg->setText("确认退出游戏吗？");
    connect(exitBtn,&QPushButton::clicked,[=]{
        //显示消息盒子
        msg->show();
         QSound::play(":res/clicked.wav");
        //事件轮询
        msg->exec();
        if(msg->clickedButton()==okBtn)
        {
            this->close();//关闭程序
        }
        else
        {
            msg->close();//关闭信息盒子
        }
    });
}

void GameRoom::paintEvent(QPaintEvent *event)
{
    //创建绘画者
    QPainter paint(this);
    //创建画板,不带有参数
    QPixmap pix;
    //load方法，加载资源或者数据
    //游戏区域
    pix.load(":res/game_room.png");
    paint.drawPixmap(0,0,800,800,pix);
    //控制区域
    pix.load(":res/bg1.png");
    paint.drawPixmap(800,0,201,900,pix);

    //绘制蛇：蛇头+蛇身+蛇尾

    //绘制蛇头的上下左右
    if(moveDirect==kSnakeDirect::UP)
    {
        pix.load(":res/rescopy.png");//加载资源
    }
    else if(moveDirect == kSnakeDirect::DOWN)
    {
        pix.load(":res/rescopy1.png");//加载资源
    }
    else if(moveDirect==kSnakeDirect::LEFT)
    {
        pix.load(":res/rescopy 2.png");//加载资源
    }
    else
    {
        pix.load(":res/rescopy3.png");//加载资源
    }
    //获取链表的头结点
    auto snakeHeadNode=snakeList.front();
    //画家绘画，给这个结点绘制pix里面的资源
   paint.drawPixmap(snakeHeadNode.x(),snakeHeadNode.y(),snakeHeadNode.width(),snakeHeadNode.height(),pix);

   //绘制蛇身
   pix.load(":res/rescopy 5.png");
   for(int i=1;i<snakeList.size()-1;i++)
   {
       auto node=snakeList.at(i);
       paint.drawPixmap(node.x()+2,node.y(),node.width()-3,node.height(),pix);
   }
   //绘制蛇尾
   auto TailNode = snakeList.back();
   paint.drawPixmap(TailNode.x()+2,TailNode.y(),TailNode.width()-3,TailNode.height(),pix);
    //绘制食物
   pix.load(":res/food.bmp");
   paint.drawPixmap(foodRect.x(),foodRect.y(),foodRect.width(),foodRect.height(),pix);

   //绘制分数
   pix.load(":res/sorce_bg.png");
   paint.drawPixmap(this->width()*0.85,this->height()*0.06,90,40,pix);
   QPen pen;
   pen.setColor(Qt::black);
   QFont font("方正舒体",22);
   paint.setPen(pen);
   paint.setFont(font);
   paint.drawText(this->width()*0.9,this->height()*0.1,QString("%1").arg(snakeList.size()));
    //把分数存入文件
   int c=snakeList.size();
   QFile file("D:/QT_creator_3_25/greedy_snake1/Snake/res/1.txt");
   if(file.open(QIODevice::Text|QIODevice::WriteOnly))
   {
       //输入文本和只写
   QTextStream out(&file);
   out<<c;
       //关闭文件
    file.close();
   }
   //绘制游戏失败效果
   if(checkFail())
   {
       pen.setColor(Qt::red);
       paint.setPen(pen);
       QFont font("方正舒体",50);
       paint.setFont(font);
       paint.drawText(this->width()*0.25,this->height()*0.5,QString("GAME OVER!"));
       timer->stop();
       QSound::play((":res/gameover.wav"));
       sound->stop();
   }
}

void GameRoom::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_W :
    case Qt::Key_Up :
        if(moveDirect != kSnakeDirect::DOWN)
        moveDirect = kSnakeDirect::UP;
        break;
    case Qt::Key_S :
    case Qt::Key_Down :
        if(moveDirect != kSnakeDirect::UP)
        moveDirect=kSnakeDirect::DOWN;
        break;
    case Qt::Key_D :
    case Qt::Key_Right :
        if(moveDirect != kSnakeDirect::LEFT)
        moveDirect=kSnakeDirect::RIGHT;
        break;
    case Qt::Key_A :
    case Qt::Key_Left :
        if(moveDirect != kSnakeDirect::RIGHT)
        moveDirect=kSnakeDirect::LEFT;
        break;
        //开始
     case Qt::Key_F :
        isGameStart = true;
        timer->start(moveDefount);
        sound = new QSound(":res/Trepak.wav"); //声⾳路S径
        sound->play(); //播放
        sound->setLoops(-1); //循环播放
        break;
//      //暂停
     case Qt::Key_G :
        isGameStart = false;
        timer->stop();//停止工作
        sound->stop();//停止播放
        break;
    }
}

void GameRoom::moveUp()
{
    QPointF leftTop; // 左上⻆坐标
     QPointF rightBottom; // 右下⻆坐标
     auto snakeNode = snakeList.front();
     int headX = snakeNode.x();
     int headY = snakeNode.y();
     // 如果上⾯剩余的空间不够放⼊⼀个新的节点, 相当于到墙边了, 要处理穿墙逻辑
     if(headY-kSnakeNodeWidth < 0) {
     leftTop = QPointF(headX, this->height() - kSnakeNodeHeight);
     } else {
     leftTop = QPointF(headX, headY - kSnakeNodeHeight);
     }
     rightBottom = leftTop + QPointF(kSnakeNodeWidth, kSnakeNodeHeight);
     snakeList.push_front(QRectF(leftTop, rightBottom));
}

void GameRoom::moveDown()
{
    QPointF leftTop; // 左上⻆坐标
     QPointF rightBottom; // 右下⻆坐标
     auto snakeNode = snakeList.front();
     int headX = snakeNode.x();
     int headY = snakeNode.y();
     // 如果下⾯剩余的空间不够放⼊⼀个新的节点, 相当于到墙边了, 要处理穿墙逻辑
     if(headY+kSnakeNodeWidth > this->height()-20) {
     leftTop = QPointF(headX, 0);
     } else {
     leftTop = snakeNode.bottomLeft(); //bottomLeft()：返回矩形左下⻆的坐标
     }
     rightBottom = leftTop + QPointF(kSnakeNodeWidth, kSnakeNodeHeight);
     snakeList.push_front(QRectF(leftTop, rightBottom));
}

void GameRoom::moveLeft()
{
    QPointF leftTop; // 左上⻆坐标
     QPointF rightBottom; // 右下⻆坐标
     auto snakeNode = snakeList.front();
     int headX = snakeNode.x();
     int headY = snakeNode.y();
     // 如果左⾯剩余的空间不够放⼊⼀个新的节点, 相当于到墙边了, 要处理穿墙逻辑
     if(headX-kSnakeNodeWidth < 0) {
     leftTop = QPointF(800 - kSnakeNodeWidth, headY);
     } else {
     leftTop = QPointF(headX - kSnakeNodeWidth, headY);
     }
     rightBottom = leftTop + QPointF(kSnakeNodeWidth, kSnakeNodeHeight);
     snakeList.push_front(QRectF(leftTop, rightBottom));
}

void GameRoom::moveRight()
{
    QPointF leftTop; // 左上⻆坐标
     QPointF rightBottom; // 右下⻆坐标
     auto snakeNode = snakeList.front();
     int headX = snakeNode.x();
     int headY = snakeNode.y();
     // 如果右⾯剩余的空间不够放⼊⼀个新的节点, 相当于到墙边了, 要处理穿墙逻辑
     if(headX + kSnakeNodeWidth > 780) {
     leftTop = QPointF(0, headY);
     } else {
     leftTop = snakeNode.topRight(); //topRight()：返回矩形右上⻆的位置。
     }
     rightBottom = leftTop + QPointF(kSnakeNodeWidth, kSnakeNodeHeight);
     snakeList.push_front(QRectF(leftTop, rightBottom));
}

bool GameRoom::checkFail()
{
    for(int i=0;i<snakeList.size();i++)
    {
        for(int j=i+1;j<snakeList.size();j++)
        {
            if(snakeList.at(i)==snakeList.at(j))
            {
                 return true;//游戏结束
            }
        }
    }
    return false;//游戏正常运行
}
//创建随机的食物
void GameRoom::creatNewFood()
{
    foodRect= QRectF(qrand()%(800/kSnakeNodeWidth)*kSnakeNodeWidth,qrand()%(800/kSnakeNodeHeight)*kSnakeNodeHeight,kSnakeNodeWidth,kSnakeNodeHeight);
}



